﻿using System;
using System.ComponentModel.DataAnnotations;

namespace ControleRepresentante.Logic.Models
{
    public abstract class ModelBase : IEquatable<ModelBase>
    {
        protected ModelBase()
        {
            Id = Guid.NewGuid();
        }

        [ScaffoldColumn(false)]
        public virtual Guid Id { get; set; }

        private static bool IsTransient(ModelBase modelBase)
        {
            return modelBase != null && modelBase.Id == Guid.Empty;
        }

        private Type GetUnproxiedType()
        {
            return GetType();
        }

        public virtual bool Equals(ModelBase other)
        {
            if (other == null)
            {
                return false;
            }

            if (ReferenceEquals(this, other))
            {
                return true;
            }

            if (IsTransient(this) || IsTransient(other) || Id != other.Id)
            {
                return false;
            }

            Type otherType = other.GetUnproxiedType();
            Type thisType = GetUnproxiedType();
            return thisType.IsAssignableFrom(otherType) || otherType.IsAssignableFrom(thisType);
        }

        public override bool Equals(object obj)
        {
            return Equals(obj as ModelBase);
        }

        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }

        public static bool Equals(ModelBase a, ModelBase b)
        {
            if (a != null) return a.Equals(b);
            if (b != null) return b.Equals(a);
            return true;
        }
    }
}